//#include "stdafx.h"
#include "Mixer.h"
#include <stdlib.h>
#include <memory.h>

CMixer::CMixer(void)
	: nInChnls(0)
	, nOutChnls(0)
	, Cmp(NULL,NULL)
	, nSmpls(0)
	, plibuf(NULL)
	, pribuf(NULL)
	, pIcs(NULL)
	, pOcs(NULL)
	, UseCmps(false)
	, SPS(44100)
	, plobuf(NULL)
	, probuf(NULL)
{
}

CMixer::~CMixer(void)
{
	if(plibuf)
	{
		delete[] plibuf;
		delete[] pribuf;
	}
	if(plobuf)
	{
		delete[] plobuf;
		delete[] probuf;
	}
	if(pIcs)
		free(pIcs);
	if(pOcs)
		free(pOcs);
}

int CMixer::SetInputChannels(CChannelForMixer** pChnlPtrArray,int n)
{
	if(n<0)
		return 0;
	if(pIcs)
		free(pIcs);
	pIcs=(CChannelForMixer**)malloc(n*sizeof(CChannelForMixer*));
	for(int i=0;i<n;++i)
	{
		if(pChnlPtrArray[i]->type!=NORMAL_IN&&pChnlPtrArray[i]->type!=HOST_IN)
		{
			pChnlPtrArray[i]->type=NORMAL_IN;
		}
		pIcs[i]=pChnlPtrArray[i];
	}
	nInChnls=n;
	return n;
}

int CMixer::SetOutputChannels(CChannelForMixer** pChnlPtrArray,int n)
{
	if(n<0)
		return 0;
	if(pOcs)
		free(pOcs);
	pOcs=(CChannelForMixer**)malloc(n*sizeof(CChannelForMixer*));
	for(int i=0;i<n;++i)
	{
		if(pChnlPtrArray[i]->type!=NORMAL_OUT&&pChnlPtrArray[i]->type!=HOST_OUT)
		{
			pChnlPtrArray[i]->type=NORMAL_OUT;
		}
		pOcs[i]=pChnlPtrArray[i];
	}
	nOutChnls=n;
	return n;
}

int CMixer::SetBufferSize(int nSamples)
{
	if(nSamples<0)
		return 0;
	nSmpls=nSamples;
	if(plibuf)
	{
		delete[] plibuf;
		delete[] pribuf;
	}
	if(plobuf)
	{
		delete[] plobuf;
		delete[] probuf;
	}
	plibuf=new float[nSmpls];
	pribuf=new float[nSmpls];
	plobuf=new float[nSmpls];
	probuf=new float[nSmpls];
	Cmp.SetBufferSize(nSmpls);
	Cmp.Compressor_Change_Preset(0);
	return nSmpls;
}

bool CMixer::EnableCompressor(bool fEnabled)
{
	UseCmps=fEnabled;
	return false;
}

bool CMixer::ClearChannels(void)
{
	if(pIcs)
		free(pIcs);
	if(pOcs)
		free(pOcs);
	pIcs=NULL;
	pOcs=NULL;
	nInChnls=0;
	nOutChnls=0;
	return false;
}

int CMixer::GetBufferSize(void)
{
	return nSmpls;
}

int CMixer::Process(void)
{
	size_t sz=nSmpls*sizeof(float);
	memset(plobuf,0,sz);
	memset(probuf,0,sz);
	int i=0,j=0;
	for(i=0;i<nInChnls;++i)
	{
		if (pIcs[i]->IsPassBy)
			continue;
		memset(plibuf,0,sz);
		memset(pribuf,0,sz);
		if(pIcs[i]->ProcessData(plibuf,pribuf,nSmpls)>0)
		{
			for(j=0;j<nSmpls;++j)
			{
				plobuf[j]+=plibuf[j];
				probuf[j]+=pribuf[j];
			}
		}
	}
	float m=nInChnls;
	m=1.0f/m;
	if(UseCmps)
	{
		for(i=0;i<nSmpls;++i)
		{
			plobuf[i]*=m;
			probuf[i]*=m;
		}
		Cmp.out(plobuf,probuf);
	}
	for(i=0;i<nOutChnls;++i)
	{
		if (pOcs[i]->IsPassBy)
			continue;
		pOcs[i]->ProcessData(plobuf,probuf,nSmpls);
	}
	return 0;
}

long CMixer::SetSampleRate(long nSamplePerSec)
{
	if(nSamplePerSec<0)
		return 0;
	SPS=nSamplePerSec;
	Cmp.SetSampleRate((unsigned int)SPS);
	Cmp.Compressor_Change_Preset(0);
	return SPS;
}

long CMixer::GetSampleRate(void)
{
	return SPS;
}
